package com.jintoufs.util.date;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.apache.commons.lang.StringUtils;

public class
		DateOperator {

	public static boolean isSameDay(Date begin, Date end) {
		String bds = DateOperator.formatDate(begin);
		String eds = DateOperator.formatDate(end);
		if (bds.equals(eds)) {
			return true;
		}
		return false;
	}

	public static Date getTodayWithoutTime() {
		return DateOperator.parse(DateOperator.formatDate(new Date(), false),
				false);
	}

	public static Long getDays(Date startDate, Date endDate) {
		Long days = new Long(0);
		if (startDate != null && endDate != null)
			days = ((endDate.getTime() - startDate.getTime()) / 1000 / 60 / 60 / 24);
		return days;
	}

	public static Long getHours(Date startDate, Date endDate) {
		Long hours = new Long(0);
		if (startDate != null && endDate != null)
			hours = ((endDate.getTime() - startDate.getTime()) / 1000 / 60 / 60);
		return hours;
	}

	public static Long getMinutes(Date startDate, Date endDate) {
		Long minute = new Long(0);
		if (endDate != null && startDate != null)
			minute = ((endDate.getTime() - startDate.getTime()) / 1000 / 60);
		return minute;
	}

	public static Date addMonthes(Date date, int monthes) {
		if (date == null)
			return null;
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(GregorianCalendar.MONTH, monthes);
		return calendar.getTime();
	}

	public static int getMonthes(Date date1, Date date2) {
		long miu = getMinutes(date1, date2);
		return (int) (miu / (60 * 24 * 31));
	}

	public static Date addYears(Date date, int years) {
		if (date == null)
			return null;
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(GregorianCalendar.YEAR, years);
		return calendar.getTime();
	}

	/**
	 * 取得每月的最后一天
	 * 
	 * @param year
	 * @param month12
	 *            实际月份1-12
	 * @return
	 */
	public static Date getLastDayOfMonth12(int year, int month12) {
		return getLastDayOfMonth11(year, month12 - 1);
	}

	/**
	 * 取得每月的第一天
	 * 
	 * @param year
	 * @param month12
	 *            实际月份1-12
	 * @return
	 */
	public static Date getFirstDayOfMonth12(int year, int month12) {
		return getFirstDayOfMonth11(year, month12 - 1);
	}

	/**
	 * 把一个日期值添加某些天,在查询条件当中如果取两个日期之前进行查询 一般情况下要把截止日期加上1天
	 * 
	 * @param date
	 *            原来的日期
	 * @param days
	 *            要添加的天数
	 * @return 加完后的日期,如果传入的Date为null则也返回null
	 */

	public static Date addHours(Date date, int hour) {
		if (date == null)
			return null;
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(GregorianCalendar.HOUR_OF_DAY, hour);
		return calendar.getTime();
	}

	/**
	 * 取得每月的最后一天
	 * 
	 * @param year
	 * @param month11
	 *            计算机月份0-11
	 * @return
	 */
	public static Date getLastDayOfMonth11(int year, int month11) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.set(year, month11, 01);
		calendar.set(GregorianCalendar.DAY_OF_MONTH,
				calendar.getActualMaximum(GregorianCalendar.DAY_OF_MONTH));

		return calendar.getTime();
	}

	/**
	 * 取得每月的第一天
	 * 
	 * @param year
	 * @param month11
	 *            计算机月份0-11
	 * @return
	 */
	public static Date getFirstDayOfMonth11(int year, int month11) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.set(year, month11, 01);
		return calendar.getTime();
	}

	public static int compareYear(Date startDate, Date endDate) {
		Long years = new Long(0);
		if (startDate != null && endDate != null)
			years = ((endDate.getTime() - startDate.getTime()) / 1000 / 60 / 60
					/ 24 / 365);
		if (years.intValue() == 0) {
			return years.intValue();
		}
		if (addYears(startDate, years.intValue()).after(endDate)
				|| addYears(startDate, years.intValue()).equals(endDate)) {
			return years.intValue();
		} else {
			return years.intValue() - 1;
		}
	}

	public static int compareMonthes(Date startDate, Date endDate) {
		Long monthes = new Long(0);
		if (startDate != null && endDate != null)
			monthes = ((endDate.getTime() - startDate.getTime()) / 1000 / 60
					/ 60 / 24 / 31);
		if (monthes.intValue() == 0) {
			return monthes.intValue();
		}
		if (addMonthes(startDate, monthes.intValue()).before(endDate)
				|| addMonthes(startDate, monthes.intValue()).equals(endDate)) {
			return monthes.intValue();
		} else {
			return monthes.intValue() - 1;
		}
	}

	@SuppressWarnings("static-access")
	public static int compareMonthes_1(Date startDate, Date endDate) {
		BigDecimal monthes = new BigDecimal(0);
		if (startDate != null && endDate != null)
			monthes = monthes.valueOf((endDate.getTime() - startDate.getTime())
					/ 1000f / 60f / 60f / 24f / 31f);
		return monthes.setScale(0, BigDecimal.ROUND_FLOOR).intValue();
	}

	@SuppressWarnings("static-access")
	public static Long compareWeek(Date startDate, Date endDate) {
		BigDecimal days = new BigDecimal(0);
		if (startDate != null && endDate != null)
			days = days.valueOf((endDate.getTime() - startDate.getTime())
					/ 1000 / 60 / 60 / 24 / 7);
		return days.setScale(0, BigDecimal.ROUND_FLOOR).longValue();
	}

	public static Long compareDays(Date startDate, Date endDate) {
		return getDays(startDate, endDate);
	}

	public static Long compareHours(Date startDate, Date endDate) {
		return getHours(startDate, endDate);
	}

	public static Long compareMinutes(Date startDate, Date endDate) {
		return getMinutes(startDate, endDate);
	}

	public static int getYear(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		return calendar.get(GregorianCalendar.YEAR);
	}

	/**
	 * @param date
	 * @return 0-11,计算机月份
	 */
	public static int getMonth11(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		return calendar.get(GregorianCalendar.MONTH);
	}

	public static int getHour(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		return calendar.get(GregorianCalendar.HOUR_OF_DAY);
	}

	public static int getMinute(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		return calendar.get(GregorianCalendar.MINUTE);
	}

	public static int getSecond(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		return calendar.get(GregorianCalendar.SECOND);
	}

	/**
	 * @param date
	 * @return 1-12,实际月份
	 */
	public static int getMonth12(Date date) {
		return getMonth11(date) + 1;
	}

	public static Date addDays(Date date, int days) {
		if (date == null)
			return null;
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(GregorianCalendar.DAY_OF_YEAR, days);
		return calendar.getTime();
	}

	public static Date createDate(int year, int month, int day) {
		return createDate(year, month, day, 0, 0, 0);
	}

	public static Date createDate(int year, int month, int day, int hourOfDay,
			int minute, int second) {
		return new GregorianCalendar(year, month, day, hourOfDay, minute,
				second).getTime();
	}

	public static String month2String(int m) {
		if (m < 10) {
			return "0" + String.valueOf(m);
		} else {
			return String.valueOf(m);
		}
	}

	public static int getDay(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		return calendar.get(GregorianCalendar.DAY_OF_MONTH);
	}

	public static Date truncDate(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.set(GregorianCalendar.HOUR_OF_DAY, 0);
		calendar.set(GregorianCalendar.MINUTE, 0);
		calendar.set(GregorianCalendar.SECOND, 0);
		calendar.set(GregorianCalendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	//

	public static final String FORMAT_STR = "yyyy-MM-dd";

	public static final String FORMAT_STR_WITH_TIME = "yyyy-MM-dd HH:mm:ss";

	public static final SimpleDateFormat DEFAULT_DATE_FORMATER_WITH_TIME = new SimpleDateFormat(
			FORMAT_STR_WITH_TIME);

	public static final SimpleDateFormat DEFAULT_DATE_FORMATTER = new SimpleDateFormat(
			FORMAT_STR);

	public static Date parse(String dateStr, boolean isMustTime) {
		try {
			if (isMustTime) {
				return DEFAULT_DATE_FORMATER_WITH_TIME.parse(dateStr);
			} else {
				return DEFAULT_DATE_FORMATTER.parse(dateStr);
			}
		} catch (Exception e) {
			return null;
		}

	}

	public static Date parse(String dateString, String formatString) {
		if (StringUtils.isBlank(dateString)) {
			return null;
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				formatString != null ? formatString : FORMAT_STR);
		try {
			return dateFormat.parse(dateString);
		} catch (ParseException ex1) {
			try {
				dateFormat.applyLocalizedPattern(FORMAT_STR);
				return dateFormat.parse(dateString);
			} catch (ParseException ex2) {
				try {
					dateFormat.applyLocalizedPattern(FORMAT_STR_WITH_TIME);
					return dateFormat.parse(dateString);
				} catch (ParseException ex) {
					throw new RuntimeException("error.dateFormatError");
				}
			}
		}
	}

	public static String formatDate(Date date) {
		return formatDate(date, false);
	}

	public static String formatDate(Date date, boolean withTime) {
		if (withTime) {
			return formatDate(date, DEFAULT_DATE_FORMATER_WITH_TIME);
		} else {
			return formatDate(date, DEFAULT_DATE_FORMATTER);
		}
	}

	public static String formatDate(Date date, String formatString) {
		return formatDate(date, new SimpleDateFormat(formatString));
	}

	public static String formatDate(Date date, DateFormat dateFormat) {
		return date != null ? dateFormat.format(date) : "";
	}

	public static boolean isWeekEnd(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		if (c.get(Calendar.DAY_OF_WEEK) == 7
				|| c.get(Calendar.DAY_OF_WEEK) == 1)
			return true;
		return false;
	}

	/**
	 * 清空日期对象的时部
	 * 
	 * @param current
	 */
	public static Calendar clearTimePart(Calendar current) {

		if (current == null)
			throw new RuntimeException("Calendar instance is avaliable!");

		current.set(Calendar.HOUR_OF_DAY, 0);
		current.set(Calendar.MINUTE, 0);
		current.set(Calendar.SECOND, 0);
		current.set(Calendar.MILLISECOND, 0);
		
		return current;
	}

	/**
	 * 清空日期对象的时部
	 * 
	 * @param date
	 */
	public static Date clearTimePart(Date date) {

		if (date == null)
			throw new RuntimeException("Date instance is avaliable!");

		Calendar current = Calendar.getInstance();
		current.setTime(date);

		current.set(Calendar.HOUR_OF_DAY, 0);
		current.set(Calendar.MINUTE, 0);
		current.set(Calendar.SECOND, 0);
		current.set(Calendar.MILLISECOND, 0);

		return current.getTime();
	}

}
